package generic.net.server;

import generic.net.Message;
import generic.net.Peer;
import generic.net.Request;
import generic.net.Response.Status;
import generic.net.observers.MessageObserver;
import generic.net.observers.RequestObserver;
import java.util.HashMap;

/**
 * The ServiceManager manages a collection of services for a single server.
 * @author Adam Scarr <scarr.adam@gmail.com>
 */
public class ServiceManager implements MessageObserver, RequestObserver {
    private HashMap<String, Service> services = new HashMap<String, Service>();
    private Server server;

    public ServiceManager(Server server) {
        this.server = server;
    }

    /**
     * When the server receives a message it notifys all listening services
     * and any (one or more) may respond.
     * @param peer      The peer that sent the message.
     * @param message   The message.
     */
    public synchronized void messageReceived(Peer peer, Message message) {
        // Do you touch yourself at night.
    }

    /**
     * When the server receives a request, only the service responsible for
     * the request is notified.
     *
     * @param peer      The peer that sent the message.
     * @param request   The message.
     */
    public synchronized void requestReceived(Peer peer, Request request) {
        Service service = services.get(request.getServiceProvider());
        if (service != null) {
            System.out.println("[ServiceManager] Received " + request.getServiceProvider() + " : " + request.getRequestType() + ". Handing off response to " + service.getName());
            service.requestReceived(peer, request, server);
            return;
        }
        System.out.println("[ServiceManager] Service '" + request.getServiceProvider() + "' does not exist!");
        peer.sendResponse(request, Status.NO_SUCH_SERVICE);
    }

    public synchronized  void add(Service service) {
        System.out.println("[ServiceManager] Added new service provider: " + service.getName());
        services.put(service.getName(), service);
    }

    public synchronized void remove(Service service) {
        services.remove(service.getName());
    }
}
